import shopping_data 

Xtrain,Ytrain,Xtest,Ytest = shopping_data.load_data()

print(Xtrain.shape)
print(Ytrain.shape)
print(Xtest.shape)
print(Ytest.shape)

# keras Embedding  嵌入层
# 将正整数(索引值)转换为固定尺寸的稠密向量 

# 我们用程序去遍历语料中的句子  
# 如果是中文需要加进行分词
# 这个过程汇总统计全体语料中的所有词语  
# 假设我们的数据中又1w个词语  
# 那就把他们放到python的数组或字典结构中  
# 排序方法可以有拼音 笔画 随机等  
# 最后每个词在数组中会有一个位置索引  

# cocalen 词典的词汇数量
# word_index 包含全语料的词典
vocalen,word_index = shopping_data.createWordIndex(Xtrain,Xtest)
print(vocalen,word_index)

#我 是 你爹 = [100,150,199]
Xtrain_index = shopping_data.word2Index(Xtrain,word_index)
Xtest_index = shopping_data.word2Index(Xtest,word_index)

# 因为句子长短不一 
# 最后得到每句话索引向量长短不一
# 所以句子需要一个对齐的操作  
from keras.preprocessing import sequence

maxlen = 25
#                   把序列按照maxlen进行对齐
Xtrain_index = sequence.pad_sequences(Xtrain_index,maxlen=maxlen)
Xtest_index = sequence.pad_sequences(Xtest_index,maxlen=maxlen)

from keras.models import Sequential
from keras.layers import Dense, Embedding, LSTM #, Flatten

#创建模型
model = Sequential()
# trainable=False 冻结嵌入层参数 
# 不训练词嵌入矩阵 可开关 效果不一样
model.add(Embedding(trainable=True,input_dim=vocalen,ouput_dim=300,input_length=maxlen))

# RNN的词向量矩阵不再需要平铺
# model.add(Flatten())
# model.add(Dense(units=256,activation='relu'))
# model.add(Dense(units=256,activation='relu'))
# model.add(Dense(units=256,activation='relu'))

# 两层lstm
model.add(LSTM(128,return_sequences=True))
model.add(LSTM(128))
# 多层RNN 前面的层需要再序列的每一步都输出结果  
# 作为下一步的输入  
# 所以第一层lstm需配置return_sequences  
# 默认是false只在最后输出结果  


model.add(Dense(units=1,activation='sigmoid'))
# 损失函数 二分类交叉熵代函数 
# 梯度优化器 动量的自适应优化器 比sgd更快更好
model.compile(loss='binary_crossentropy',
              optimizer='adam',
              metrics=['accuracy']
              )

model.fit(Xtrain_index,Ytrain,batch_size=512,epochs=200)

score, acc = model.evaluate(Xtest_index,Ytest)
print(score, acc)


# 结论：
# 当我们把嵌入式层的训练打开后  
# 嵌入层的参数矩会同步参与网络训练  
# 而我们的嵌入层参数数量有vocalen9512 x 300 
# 比后面NN中的参数还要多  
# 这样导致训练过程中  
# 嵌入层的参数占用很大比重  
# 也就是训练的重心都跑到了词嵌入矩阵参数上  
# 导致lstm和full connection在打开trainable后的训练差距不大  
# 我们这的语料数据集不是很丰富   
# 最后达到的效果就不突出  
# 所以更常用的方法是  
# 使用别人在海量数据集上训练出来的词向量  
